<!--
 * @Author: 赵宇
 * @Description: 
 * @Date: 2023-03-03 14:11:11
 * @LastEditTime: 2023-03-03 14:24:36
 * @LastEditors: zhao 13370229059@163.com
 * @FilePath: \pcj\src\page\product\components\calculator.vue
-->
<template>
    <div class="num">
      <el-button size="mini" plain type="primary" v-for="item in custom" :key="item.id" @click="onTagChange(item)">
        {{ item.label }}
      </el-button>
      <ul class="num-content">
        <li class="num-content-show">
          {{ params.numActiveData.join('') }}
        </li>
        <li class="num-content-calculator">
          <div v-for="(item, index) in numData" :key="index" class="dis-flex w-100">
            <div
              v-for="row in item"
              :key="row.label"
              class="num-content-calculator-button"
              :style="{ width: row.width || '40px', flex: row.width ? 2 : 1, borderRadius: row.width ? '20px' : '50%' }"
              @click="onCalculatorChange(row)"
            >
              {{ row.text }}
            </div>
          </div>
        </li>
      </ul>
      <el-button type="primary" @click="check(true)" class="mt-20" size="mini" icon="el-icon-s-check">验证</el-button>
      <el-button type="danger" @click="close" class="mt-20" size="mini" icon="el-icon-circle-close">清空</el-button>
    </div>
  </template>
  
  <script setup>
  let $message = inject('$message');
  
  let numData = [
    [
      { text: '(', val: '' },
      { text: ')', val: '' },
      { text: '←', val: '', width: '80px' }
    ],
    [
      { text: '1', val: '' },
      { text: '2', val: '' },
      { text: '3', val: '' },
      { text: '+', val: '' }
    ],
    [
      { text: '4', val: '' },
      { text: '5', val: '' },
      { text: '6', val: '' },
      { text: '-', val: '' }
    ],
    [
      { text: '7', val: '' },
      { text: '8', val: '' },
      { text: '9', val: '' },
      { text: '*', val: '' }
    ],
    [
      { text: '0', val: '', width: '80px' },
      { text: '.', val: '' },
      { text: '/', val: '' }
    ]
  ];
  let params = reactive({
    numActiveData: [],
    valActiveData: []
  });
  let props = defineProps({
    custom: {
      type: Array,
      default: () => {
        return [];
      }
    },
    data: {
      type: Object,
      default: () => {
        return {};
      }
    }
  });
  watch(
    () => props.data,
    val => {
      params.numActiveData = val.formulaName ? JSON.parse(val.formulaName) : [];
      params.valActiveData = val.formulaLabel ? JSON.parse(val.formulaLabel) : [];
    },
    {
      immediate: true
    }
  );
  const onTagChange = val => {
    params.numActiveData.push(val.label);
    params.valActiveData.push(val.attributeName);
  };
  const onCalculatorChange = val => {
    if (val.text === '←') {
      params.numActiveData.splice(params.numActiveData.length - 1, 1);
      params.valActiveData.splice(params.valActiveData.length - 1, 1);
      return;
    }
    params.numActiveData.push(val.text);
    params.valActiveData.push(val.text);
  };
  const getRandomNum = (min, max) => {
    return min + Math.round((max - min) * Math.random());
  };
  const close = () => {
    params.numActiveData = [];
    params.valActiveData = [];
  };
  // 验证判断 val 控制 是否显示验证成功提示
  const check = (val = false) => {
    let arr = params.numActiveData;
    if (!arr.length) {
      $message('计算公式为空！');
      return;
    }
    let calArr = params.numData.reduce((t, r) => {
      t.push(...r.map(n => n.text));
      return t;
    }, []);
    try {
      let replaceArr = [];
      arr.map(r => {
        if (calArr.find(n => n === r)) {
          replaceArr.push(r);
          return;
        }
        replaceArr.push(getRandomNum(1, 9999999));
      });
      let res = eval(replaceArr.join(''));
      // 结果为无穷数也会验证失败
      if (res === Infinity) {
        $message('验证失败，请仔细检查');
        return;
      }
      let type = false;
      arr.map((r, i) => {
        if (type) return;
        if (calArr.find(n => n === r)) return;
        type = arr[i + 1] ? !['(', ')', '+', '-', '*', '/'].includes(arr[i + 1]) : false;
        if (type) {
          $message(`${r} 后面 ${arr[i + 1]} 有误`);
          return;
        }
        type = arr[i - 1] ? !['(', ')', '+', '-', '*', '/'].includes(arr[i - 1]) : false;
        if (type) {
          $message(`${r} 前面 ${arr[i - 1]} 有误`);
        }
      });
      if (type) return;
      if (val) $message('验证');
      return true;
    } catch (_) {
      $message('验证失败，请仔细检查');
    }
  };
  </script>
  
  <style lang="scss" scoped>
  .num {
    width: 100%;
  }
  .num-content {
    display: flex;
    margin-top: 5px;
    &-show {
      background-color: #f4f4f5;
      color: #bcbec2;
      padding: 5px;
      margin: 5px;
      flex: 1;
      border: 1px solid #e4e7ed;
      border-radius: 4px;
      letter-spacing: 2px;
      line-height: 1.5;
    }
    &-calculator {
      width: 180px;
      &-button {
        color: #fff;
        text-align: center;
        border-radius: 50%;
        position: relative;
        background-color: #a9c7da;
        height: 40px;
        line-height: 40px;
        margin-top: 5px;
        margin-left: 5px;
        transition: all 0.4s cubic-bezier(0.85, 0.05, 0.18, 1.35);
        user-select: none;
        box-shadow: 0px -6px 10px white, 0px 4px 15px rgb(0 0 0 / 15%);
        &:hover {
          opacity: 0.8;
          cursor: pointer;
        }
        &:active {
          box-shadow: 0 15px 20px rgb(0 0 0 / 2%);
        }
      }
    }
  }
  </style>
  